#ifndef EXTERNALPLANT_H
#define EXTERNALPLANT_H

#include "SISOModel.h"

#include "plant.h"

namespace RafMat {
namespace SimEngine {

// Deklaracja zapowiadająca
class ExternalPlant;

/**
    Alias na zręczny wskaźnik dla DiscreteObject.
*/
typedef boost::shared_ptr<ExternalPlant> ExternalPlantSPtr;


class ExternalPlant : public SISOModel
{
public:
    /**
        Tworzy instancję obiektu ExternalPlant. Zadaniem konstruktora jest
        powiązanie obiektu z symulatorem.

        \param [in] simulator Referencja do obiektu symulatora.
    */
    explicit ExternalPlant(const SimInterface::ISimulator& simulator)
        : SISOModel(simulator) {}

    /**
        Wersja konstruktora wymuszająca nadanie nazwy obiektowi w chwili
        tworzenia.
    */
    ExternalPlant(const SimInterface::ISimulator& simulator, std::string name)
            : SISOModel(simulator, name) {}

    /** Wykonuje krok symulacji */
    double simulateStep(double inputSample);

    /** Reset modelu do stanu początkowego */
    void reset();

    bool setParameter(const std::string& param, const std::string& value) throw(std::logic_error);

    /**
        Odczytuje określony parametr.
        Klasa implementująca ma za zadanie rozróżnić czego od niej się chce
        oraz zasygnalizować ewentualny błąd parametru.

        \param [in] param parametr, który chcemy odczytać.
        \return Wartość odpowiadająca parametrowi w formie łańcucha znaków.
        \throws std::iconf_error - gdy parametr nie zgadza się
        syntaktycznie z daną implementacją.
    */
    std::string getParameter(const std::string& param) const throw(std::logic_error);

    SimFile::ConfigWriter& dumpParameters(SimFile::ConfigWriter& o) const;
private:

    AdaptiveTechniques::Plant m_plant;
};

}
}

#endif // EXTERNALPLANT_H
